unit ErrorBar;

interface

uses Classes, Controls, StdCtrls, ExtCtrls, SysUtils, Graphics, ErrorLabel;

type
  TErrorBar = class(TPanel)
  private
    FOnLabelClick: TNotifyEvent;
    procedure LabelClick(Sender: TObject);
  public
    procedure AddError(Name: string; Hint: string; Data: TObject);
    procedure RemoveError(Name: string);
    procedure AfterConstruction; override;
    procedure Clear;
  published
    property OnLabelClick: TNotifyEvent read FOnLabelClick write FOnLabelClick;
    destructor Destroy; override;
  end;

implementation

uses Types, Windows;

{ TErrorBar }

procedure TErrorBar.AddError(Name: string; Hint: string; Data: TObject);
var
  ALabel: TErrorLabel;
  Handle: HDC;
  Size: TSize;
  I: Integer;
begin
  ALabel := nil;
  // Check for an existing error label for the same name:
  for I := 0 to ControlCount - 1 do
    if TErrorLabel(Controls[I]).Caption = Name then
    begin
      ALabel := Controls[I] as TErrorLabel;
      break;
    end;

  // Create new error label:
  if ALabel = nil then
  begin
    ALabel := TErrorLabel.Create(self);
    ALabel.Parent := self;
    ALabel.Caption := Name;
    ALabel.Align := alLeft;
    Handle := GetDC(self.Handle);
    GetTextExtentPoint32(Handle, ALabel.Caption, Length(ALabel.Caption), Size);
    ALabel.Width := Size.cx + 16 + 16;
    ALabel.Height := ClientHeight;
  end;

  ALabel.Hint := Hint;
  ALabel.Data := Data;
  ALabel.OnClick := LabelClick;
end;

procedure TErrorBar.AfterConstruction;
begin
  inherited;
  ShowHint := true;
end;

procedure TErrorBar.Clear;
var
  I: Integer;
begin
  for I := ControlCount - 1 downto 0 do
    RemoveControl(Controls[I]);
end;

destructor TErrorBar.Destroy;
begin
  inherited;
end;

procedure TErrorBar.LabelClick(Sender: TObject);
begin
  if (Assigned(FOnLabelClick)) then
    FOnLabelClick(Sender);
end;

procedure TErrorBar.RemoveError(Name: string);
var
  I: Integer;
begin
  for I := 0 to ControlCount - 1 do
    if TErrorLabel(Controls[I]).Caption = Name then
      Controls[I].Free;
end;

end.
